import type { SSEEvent, SSEObjectType } from '@/types'

// SSE事件处理器类型
export type SSEEventHandler = (event: SSEEvent) => void

// SSE连接状态
export enum SSEConnectionState {
  DISCONNECTED = 'disconnected',
  CONNECTING = 'connecting',
  CONNECTED = 'connected',
  ERROR = 'error',
  RECONNECTING = 'reconnecting'
}

// SSE连接选项
export interface SSEOptions {
  reconnectInterval?: number // 重连间隔（毫秒）
  maxReconnectAttempts?: number // 最大重连次数
  timeout?: number // 连接超时时间
  withCredentials?: boolean // 是否发送凭据
}

// SSE管理器类
export class SSEManager {
  private eventSource: EventSource | null = null
  private url: string = ''
  private options: Required<SSEOptions>
  private handlers = new Map<SSEObjectType, SSEEventHandler[]>()
  private generalHandlers: SSEEventHandler[] = []
  private state: SSEConnectionState = SSEConnectionState.DISCONNECTED
  private reconnectAttempts = 0
  private reconnectTimer: number | null = null
  private stateChangeHandlers: Array<(state: SSEConnectionState) => void> = []

  constructor(options: SSEOptions = {}) {
    this.options = {
      reconnectInterval: options.reconnectInterval || 3000,
      maxReconnectAttempts: options.maxReconnectAttempts || 5,
      timeout: options.timeout || 30000,
      withCredentials: options.withCredentials || false
    }
  }

  /**
   * 连接到SSE端点
   */
  connect(url: string): Promise<void> {
    return new Promise((resolve, reject) => {
      if (this.eventSource && this.state === SSEConnectionState.CONNECTED) {
        resolve()
        return
      }

      this.url = url
      this.setState(SSEConnectionState.CONNECTING)

      try {
        this.eventSource = new EventSource(url, {
          withCredentials: this.options.withCredentials
        })

        const connectTimeout = setTimeout(() => {
          this.setState(SSEConnectionState.ERROR)
          this.close()
          reject(new Error('SSE connection timeout'))
        }, this.options.timeout)

        this.eventSource.onopen = () => {
          clearTimeout(connectTimeout)
          this.setState(SSEConnectionState.CONNECTED)
          this.reconnectAttempts = 0
          console.log('SSE connected:', url)
          resolve()
        }

        this.eventSource.onmessage = (event) => {
          this.handleMessage(event)
        }

        this.eventSource.onerror = (event) => {
          clearTimeout(connectTimeout)
          console.error('SSE error:', event)
          this.setState(SSEConnectionState.ERROR)
          
          if (this.eventSource?.readyState === EventSource.CLOSED) {
            this.scheduleReconnect()
          }
          
          if (this.state === SSEConnectionState.CONNECTING) {
            reject(new Error('SSE connection failed'))
          }
        }

      } catch (error) {
        this.setState(SSEConnectionState.ERROR)
        reject(error)
      }
    })
  }

  /**
   * 断开SSE连接
   */
  close(): void {
    if (this.reconnectTimer) {
      clearTimeout(this.reconnectTimer)
      this.reconnectTimer = null
    }

    if (this.eventSource) {
      this.eventSource.close()
      this.eventSource = null
    }

    this.setState(SSEConnectionState.DISCONNECTED)
    console.log('SSE disconnected')
  }

  /**
   * 注册特定类型事件的处理器
   */
  on(objectType: SSEObjectType, handler: SSEEventHandler): void {
    if (!this.handlers.has(objectType)) {
      this.handlers.set(objectType, [])
    }
    this.handlers.get(objectType)!.push(handler)
  }

  /**
   * 注册通用事件处理器（处理所有事件）
   */
  onAny(handler: SSEEventHandler): void {
    this.generalHandlers.push(handler)
  }

  /**
   * 注册状态变化处理器
   */
  onStateChange(handler: (state: SSEConnectionState) => void): void {
    this.stateChangeHandlers.push(handler)
  }

  /**
   * 移除事件处理器
   */
  off(objectType: SSEObjectType, handler: SSEEventHandler): void {
    const handlers = this.handlers.get(objectType)
    if (handlers) {
      const index = handlers.indexOf(handler)
      if (index > -1) {
        handlers.splice(index, 1)
      }
    }
  }

  /**
   * 移除通用事件处理器
   */
  offAny(handler: SSEEventHandler): void {
    const index = this.generalHandlers.indexOf(handler)
    if (index > -1) {
      this.generalHandlers.splice(index, 1)
    }
  }

  /**
   * 移除状态变化处理器
   */
  offStateChange(handler: (state: SSEConnectionState) => void): void {
    const index = this.stateChangeHandlers.indexOf(handler)
    if (index > -1) {
      this.stateChangeHandlers.splice(index, 1)
    }
  }

  /**
   * 清除所有处理器
   */
  clearHandlers(): void {
    this.handlers.clear()
    this.generalHandlers.length = 0
    this.stateChangeHandlers.length = 0
  }

  /**
   * 获取当前连接状态
   */
  getState(): SSEConnectionState {
    return this.state
  }

  /**
   * 检查是否已连接
   */
  isConnected(): boolean {
    return this.state === SSEConnectionState.CONNECTED
  }

  /**
   * 处理SSE消息
   */
  private handleMessage(event: MessageEvent): void {
    try {
      // 解析事件数据
      const eventData: SSEEvent = JSON.parse(event.data)
      
      // 验证事件格式
      if (!eventData.object) {
        console.warn('Invalid SSE event format:', eventData)
        return
      }

      console.log('SSE event received:', eventData.object, eventData)

      // 调用通用处理器
      this.generalHandlers.forEach(handler => {
        try {
          handler(eventData)
        } catch (error) {
          console.error('Error in general SSE handler:', error)
        }
      })

      // 调用特定类型的处理器
      const specificHandlers = this.handlers.get(eventData.object)
      if (specificHandlers) {
        specificHandlers.forEach(handler => {
          try {
            handler(eventData)
          } catch (error) {
            console.error(`Error in SSE handler for ${eventData.object}:`, error)
          }
        })
      }

    } catch (error) {
      console.error('Failed to parse SSE event:', error, event.data)
    }
  }

  /**
   * 设置连接状态
   */
  private setState(newState: SSEConnectionState): void {
    if (this.state !== newState) {
      this.state = newState
      this.stateChangeHandlers.forEach(handler => {
        try {
          handler(newState)
        } catch (error) {
          console.error('Error in state change handler:', error)
        }
      })
    }
  }

  /**
   * 安排重连
   */
  private scheduleReconnect(): void {
    if (this.reconnectAttempts >= this.options.maxReconnectAttempts) {
      console.error('Max reconnection attempts reached')
      this.setState(SSEConnectionState.ERROR)
      return
    }

    this.setState(SSEConnectionState.RECONNECTING)
    this.reconnectAttempts++

    console.log(`Scheduling SSE reconnection attempt ${this.reconnectAttempts}/${this.options.maxReconnectAttempts}`)

    this.reconnectTimer = window.setTimeout(() => {
      this.reconnect()
    }, this.options.reconnectInterval)
  }

  /**
   * 重新连接
   */
  private async reconnect(): Promise<void> {
    if (!this.url) return

    try {
      this.close()
      await this.connect(this.url)
    } catch (error) {
      console.error('SSE reconnection failed:', error)
      this.scheduleReconnect()
    }
  }
}

// 全局SSE管理器实例
const sseManager = new SSEManager({
  reconnectInterval: 3000,
  maxReconnectAttempts: 5,
  timeout: 30000
})

// 组合式API
export const useSSE = () => {
  return {
    sseManager,
    SSEConnectionState,
    
    // 便捷方法
    connect: (url: string) => sseManager.connect(url),
    disconnect: () => sseManager.close(),
    on: (objectType: SSEObjectType, handler: SSEEventHandler) => sseManager.on(objectType, handler),
    off: (objectType: SSEObjectType, handler: SSEEventHandler) => sseManager.off(objectType, handler),
    onAny: (handler: SSEEventHandler) => sseManager.onAny(handler),
    offAny: (handler: SSEEventHandler) => sseManager.offAny(handler),
    onStateChange: (handler: (state: SSEConnectionState) => void) => sseManager.onStateChange(handler),
    isConnected: () => sseManager.isConnected(),
    getState: () => sseManager.getState()
  }
}

export default sseManager